package com.nannybear.Communication;


import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * \brief Asynchronous task to launch the connection
 * \author Audrey LOISEAU
 * \date 29-04-2015
 */

/********************************* COPYRIGHT *********************************
 * Copyright (c) 2015, Audrey LOISEAU and Benjamin LANCINOT.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *************************************************************************************/

public class ConnectionTask  extends AsyncTask<Void, Integer, Void> {
    /********** DECLARATIONS **********/
    // Variables
    private ProgressDialog progressDialog;
    private final String ip;
    private final int port;
    private final static String ENCODING = "UTF-8";
    private boolean firstConnection;

    //Classes
    private Connection connection;

    /************ METHODS ************/
    /**
     * \brief Constructor
     * \param connection    The connection
     * \param ip    The NannyBear ip
     * \param port  The NannyBear port
     * \param firstConnection   True if it is the first connection
     */
    public ConnectionTask(Connection connection, String ip, int port, boolean firstConnection){
        this.connection = connection;
        this.ip = ip;
        this.port = port;
        this.firstConnection = firstConnection;
        connection.setConnected(false);
    }

    /**
     * \brief Creation of the socket, initialization of reader and writer buffers.
     */
    private void connect(){
        try {
            if(firstConnection){
                connection.setSocket(new Socket(this.ip, this.port));
                connection.changeConnectionState(true);
                connection.setReader(new BufferedReader((new InputStreamReader(connection.getSocket().getInputStream(), ENCODING))));
                connection.setWriter(new BufferedWriter((new OutputStreamWriter(connection.getSocket().getOutputStream(), ENCODING))));

                connection.changeConnectionState(true);

                connection.setPostman(new Postman(connection));
                connection.setProxyRobot(new ProxyRobot(connection));
                connection.linkObserverToSubject();
                connection.getPostman().start();
            }
            else{
                connection.setSocket(new Socket(this.ip, this.port));
                connection.setReader(new BufferedReader((new InputStreamReader(connection.getSocket().getInputStream(), ENCODING))));
                connection.setWriter(new BufferedWriter((new OutputStreamWriter(connection.getSocket().getOutputStream(), ENCODING))));
                connection.changeConnectionState(true);
            }
        }catch (UnknownHostException ex){
            Log.e("Connection", "Problem with the IP : "+ex.getMessage());
            connection.changeConnectionState(false);
        }catch (IOException ex){
            Log.e("Connection", "Problem with the port : "+ex.getMessage());
            connection.changeConnectionState(false);
        }
    }

    /**
     * \brief Pre execution of the asynchronous task to show the pop-up
     */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog = new ProgressDialog(this.connection.getActivity().getWindow().getContext());
        progressDialog.setTitle("Establishment of the connection...");
        progressDialog.setMessage("Please wait, connection in progress");
        progressDialog.setMax(100);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    /**
     * \brief If the connection is ok, send the threshold and cancel the pop-up
     */
    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        progressDialog.cancel();
        if(connection.isConnected()){
            this.connection.getActivity().sendThreshold();
        }
    }

    /**
     * \briefDisplay a progressBar during the connection
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        progressDialog.setProgress(10);
    }

    /**
     * \brief Launch the connection in background
     */
    @Override
    protected Void doInBackground(Void...params) {
        Log.e("Co", "do background");
        connect();
        publishProgress(0);
        return null;
    }
}
